package utils

import (
	"fmt"
	"strings"
)

/*
1001-1004,1053
多线程不安全
*/
type MultiIntSection struct {
	rawSections []string
	startlist   []*int64
	endlist     []*int64
}

func NewMultiIntSection(exp string) *MultiIntSection {
	rval := &MultiIntSection{}
	rval.Parse(exp)
	return rval
}

func (this *MultiIntSection) Count() int {
	return len(this.startlist)
}

func (this *MultiIntSection) String() string {
	var sb BytesBuilder
	var str string
	for i := 0; i < len(this.startlist); i++ {
		if i > 0 {
			sb.AppendStr(",")
		}
		if this.startlist[i] != nil && this.endlist[i] != nil {
			str = fmt.Sprintf("%v-%v", *this.startlist[i], *this.endlist[i])
		} else if this.startlist[i] != nil {
			str = fmt.Sprintf("%v", *this.startlist[i])
		} else if this.endlist[i] != nil {
			str = fmt.Sprintf("-%v", *this.endlist[i])
		}

		sb.AppendStr(str)
	}
	return sb.String()
}

/*
*

	-1,-2,1~100
*/
func (this *MultiIntSection) Parse(exp string) {
	exp = strings.TrimRightFunc(exp, func(r rune) bool {
		return r == ',' || r == ' ' || r == '\r' || r == '\n'
	})
	sections := strings.Split(exp, ",")

	startlist := make([]*int64, 0, len(sections))
	endlist := make([]*int64, 0, len(sections))
	rawSections := make([]string, 0, len(sections))
	for i := 0; i < len(sections); i++ {
		str := Trim(sections[i])
		if len(str) == 0 {
			continue
		}
		rawSections = append(rawSections, str)
		itms := strings.SplitN(str, "~", 2)

		v := StrToInt64Def(itms[0], 0)
		startlist = append(startlist, &v)

		if len(itms) == 2 {
			v := StrToInt64Def(itms[1], 0)
			endlist = append(endlist, &v)
		} else {
			endlist = append(endlist, nil)
		}
	}

	this.startlist = startlist
	this.endlist = endlist
	this.rawSections = rawSections
}

func (this *MultiIntSection) IsIn(val int64) string {
	idx := this.IndexVal(val)
	if idx != -1 {
		return this.rawSections[idx]
	}
	return ""
}

func (this *MultiIntSection) IndexVal(val int64) int {
	for i := 0; i < len(this.startlist); i++ {
		v1 := this.startlist[i]
		v2 := this.endlist[i]
		if v1 == nil && v2 == nil {
			continue
		}

		if v2 == nil {
			if *v1 == val {
				return i
			} else {
				continue
			}
		} else if val >= *v1 && val <= *v2 {
			return i
		}

	}
	return -1
}
